package com.alks.function.service.impl.chengKong;

import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.ImageUtils;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.common.utils.excelUtils.ExcelPoiUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.common.utils.stringUtils.ZStringUtils;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.enums.chengkong.DefineEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.config.ProfileConfig;
import com.alks.function.data.dto.PcLotHeadCountDto;
import com.alks.function.data.dto.chengKong.assort.YfBomMemoNew2Dto;
import com.alks.function.data.dto.chengKong.assort.YfBomPartNew2Dto;
import com.alks.function.data.dto.chengKong.produce.*;
import com.alks.function.data.dto.procurement.PurchaseOrderDto;
import com.alks.function.data.request.chengKong.*;
import com.alks.function.data.request.procurement.LotAndMtlRequest;
import com.alks.function.mapper.PcLotExp2Mapper;
import com.alks.function.mapper.chengKong.LargeCargoUsageMapper;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.chengKong.PcOutListMapper;
import com.alks.function.mapper.procurement.MaterialClearanceMapper;
import com.alks.function.service.chengKong.PcLotHeadService;
import com.alks.function.service.impl.PcLotExp2ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
public class PcLotHeadServiceImpl extends ServiceImpl<PcLotHeadMapper,PcLotHead> implements PcLotHeadService {

    @Resource
    private PcLotHeadMapper pcLotHeadMapper;

    @Autowired
    private MaterialClearanceMapper materialClearanceMapper;

    /**
     * 指令明细
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getStyleDetails(PcLotHeadRequest request) {
        Map map = new HashMap<>();
        SysUserTokenDTO dto = UserIdThread.get();
        //查询所有指令信息
        List<PcLotHeadDto> styleDetails = pcLotHeadMapper.getStyleDetails(request,dto);
        PageInfo page=new PageInfo(styleDetails);
        //统计订单数量预补数量
        PcLotHeadCountDto count = pcLotHeadMapper.orderCount(request,dto);
        map.put("styleDetails",styleDetails);
        map.put("total",page.getTotal());
        map.put("orderCount",count);
        return ResponseInfo.ok(map);
    }

    /**
     * 指令明细配码
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleSizeData(LotNoRequest request) {
        //指令配码明细
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(),companyId);
        PcLotHeadCountDto codeDetailsSum = pcLotHeadMapper.getCodeDetailsSum(request.getLotNo(),companyId);
        Map list = new HashMap<>();
        list.put("codeDetails", codeDetails);
        list.put("codeDetailsSum", codeDetailsSum);
        return ResponseInfo.ok(list);
    }

    /**
     * 号码明细（指令明细配码）
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleSizeData2(LotNoRequest request) {
        //指令配码明细
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails2(request.getLotNo(),request.getStyle(),companyId);
        PcLotHeadCountDto codeDetailsSum = pcLotHeadMapper.getCodeDetailsSum(request.getLotNo(),companyId);
        Map list = new HashMap<>();
        list.put("codeDetails", codeDetails);
        list.put("codeDetailsSum", codeDetailsSum);
        return ResponseInfo.ok(list);
    }

    /**
     * po号码明细
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getPoNumberDetails(LotNoRequest request) {
        Map list = new HashMap<>();
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotGroupDto> pcLotGroups = pcLotHeadMapper.PoNumberDetails(request.getLotNo(),companyId);
        BigDecimal sum= BigDecimal.ZERO;
        for (PcLotGroupDto pcLotGroup : pcLotGroups) {
            sum=sum.add(pcLotGroup.getCount());
        }
        list.put("pcLotGroups", pcLotGroups);
        list.put("sum",sum);
        return ResponseInfo.ok(list);
    }

    /**
     * po号码动态码数
     * @param map
     * @return
     */
    @Override
    public ResponseInfo getPoNumberSizeData(Map<String, String> map) {
        String sizeCode = map.get("sizeCode");
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotSizeSeqDto> list = pcLotHeadMapper.getSize(sizeCode, companyId);
        for (PcLotSizeSeqDto dto : list) {
            if (!ObjectUtils.isEmpty(dto)){
                String sizeNo=dto.getSizeNo()+DefineEnum.CHAR_SIGN.getValue();
                dto.setSizeNo(sizeNo);
            }
        }
        return ResponseInfo.ok(list);
    }

    /**
     * 指令用量明细
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleUsageDetails(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotUsageDto> usageDetails = pcLotHeadMapper.getUsageDetails(request.getLotNo(),companyId);
        return ResponseInfo.ok(usageDetails);
    }

    /**
     * 型体配楦明细
     * @param style
     * @return
     */
    @Override
    public ResponseInfo getStyleOfLastNoDetails(String style) {
        String companyId = UserIdThread.get().getCompanyId();
        List<SdStyleSizeDto> map = pcLotHeadMapper.getStyleShoeLastDetails(style,companyId);
        return ResponseInfo.ok(map);
    }

    /**
     * 配色BOM资料
     * @return
     */
    @Override
    public ResponseInfo getStyleBOMDetails(PcLotHeadRequest2 request) {
        request.setCompanyId(UserIdThread.get().getCompanyId());
        List<SdBomPartNew2Dto> bomDetails = pcLotHeadMapper.getBOMDetails(request);
        for (SdBomPartNew2Dto dto : bomDetails) {
            switch (dto.getUsageType()) {
                case "B":
                    dto.setUsageType(DefineEnum.BASIC_CODE.getValue());
                    break;
                case "M":
                    dto.setUsageType(DefineEnum.MIDDLE_CODE.getValue());
                    break;
                case "F":
                    dto.setUsageType(DefineEnum.FULL_CODE.getValue());
                    break;
                default:
                    dto.setUsageType(null);
            }
        }
        return ResponseInfo.ok(bomDetails);
    }

    /**
     * 新增指令
     * @param request
     * @return
     */
    @Override
    public ResponseInfo addStyle(PcLotHeadRequest request) {
        if (request.getLotNo().isEmpty()){
            return ResponseInfo.error("指令为空!");
        }
        if (request.getStyle().isEmpty()){
            return ResponseInfo.error("型体为空!");
        }
        if (request.getStyleType().isEmpty()){
            return ResponseInfo.error("新旧型体为空!");
        }
        if (request.getColor().isEmpty()){
            return ResponseInfo.error("颜色为空!");
        }
        if (request.getOrderStartDate()==null){
            return ResponseInfo.error("下单日期为空!");
        }
        if (request.getCustomPo().isEmpty()){
            return ResponseInfo.error("合同号为空!");
        }
        if (request.getDeliveryStartDate()==null){
            return ResponseInfo.error("客人交期为空!");
        }
        if (request.getSeason().isEmpty()){
            return ResponseInfo.error("季度资料为空!");
        }

        //判断指令是否存在
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo,request.getLotNo());
        PcLotHead head = pcLotHeadMapper.selectOne(wrapper);
        if (head!=null){
            return ResponseInfo.error("指令已存在!");
        }
        PcLotHead pcLotHead = new PcLotHead();
        BeanUtil.copyProperties(request,pcLotHead);
        String userName = UserIdThread.get().getUserName();
        pcLotHead.setUserId(userName);
        pcLotHead.setSysDate(LocalDateTime.now());
        pcLotHead.setCompanyId(companyId);
        pcLotHead.setDeliveryDate(request.getDeliveryStartDate());
        pcLotHead.setOrderDate(request.getOrderStartDate());
        pcLotHead.setProcessAll(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessUpper(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessCut01(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessCut02(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessCut03(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessStitch(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessSole(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setProcessLast(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setLacing(DefineEnum.CHECKOUT_FLAG_N.getValue());
        pcLotHeadMapper.insert(pcLotHead);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 取大底入货号码明细查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getSoleDetails(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> soleDetails = pcLotHeadMapper.getSoleDetails(request.getLotNo(),companyId);
        PcLotHeadCountDto soleDetailsSum = pcLotHeadMapper.getSoleDetailsSum(request.getLotNo(),companyId);
        Map list = new HashMap<>();
        list.put("codeDetails", soleDetails);
        list.put("codeDetailsSum", soleDetailsSum);
        return ResponseInfo.ok(list);
    }

    /**
     * 取鞋面生产号码明细查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStitchDetails(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> stitchDetails = pcLotHeadMapper.getStitchDetails(request.getLotNo(),companyId);
        PcLotHeadCountDto stitchDetailsSum = pcLotHeadMapper.getStitchDetailsSum(request.getLotNo(),companyId);
        Map list = new HashMap<>();
        list.put("codeDetails", stitchDetails);
        list.put("codeDetailsSum", stitchDetailsSum);
        return ResponseInfo.ok(list);
    }

    /**
     * 取成型生产号码明细查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getLastDetails(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> lastDetails = pcLotHeadMapper.getLastDetails(request.getLotNo(),companyId);
        PcLotHeadCountDto lastDetailsSum = pcLotHeadMapper.getLastDetailsSum(request.getLotNo(),companyId);
        Map list = new HashMap<>();
        list.put("codeDetails", lastDetails);
        list.put("codeDetailsSum", lastDetailsSum);
        return ResponseInfo.ok(list);
    }

    /**
     * 取大底入货号码明细
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getSoleDetailsAdd(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
        if (!ObjectUtils.isEmpty(codeDetails)){
            List<PcLotDetail> pcLotDetails = codeDetails.stream().map(s -> {
                PcLotDetail pcLotDetail = new PcLotDetail();
                BeanUtil.copyProperties(s, pcLotDetail);
                pcLotDetail.setLotNo(request.getLotNo());
                pcLotDetail.setCompanyId(companyId);
                return pcLotDetail;
            }).collect(Collectors.toList());
            delPcLotDetailSole(request.getLotNo(), companyId);
            pcLotHeadMapper.addSoleDetails(pcLotDetails);
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除大底入货号码
     * @param lotNo
     * @param companyId
     */
    private void delPcLotDetailSole(String lotNo, String companyId) {
        pcLotHeadMapper.delSoleDetails(lotNo, companyId);
    }

    /**
     * 取鞋面生产号码
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getStitchDetailsAdd(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
        if (!ObjectUtils.isEmpty(codeDetails)){
            List<PcLotDetail> pcLotDetails = codeDetails.stream().map(s -> {
                PcLotDetail pcLotDetail = new PcLotDetail();
                BeanUtil.copyProperties(s, pcLotDetail);
                pcLotDetail.setLotNo(request.getLotNo());
                pcLotDetail.setCompanyId(companyId);
                return pcLotDetail;
            }).collect(Collectors.toList());
            delPcLotDetailStitch(request.getLotNo(), companyId);
            pcLotHeadMapper.addStitchDetails(pcLotDetails);
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除鞋面生产号码
     * @param lotNo
     * @param companyId
     */
    private void delPcLotDetailStitch(String lotNo, String companyId) {
        pcLotHeadMapper.delStitchDetails(lotNo, companyId);
    }

    /**
     * 取成型生产号码
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getLastDetailsAdd(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
        if (!ObjectUtils.isEmpty(codeDetails)){
            List<PcLotDetail> pcLotDetails = codeDetails.stream().map(s -> {
                PcLotDetail pcLotDetail = new PcLotDetail();
                BeanUtil.copyProperties(s, pcLotDetail);
                pcLotDetail.setLotNo(request.getLotNo());
                pcLotDetail.setCompanyId(companyId);
                return pcLotDetail;
            }).collect(Collectors.toList());
            delPcLotDetailLast(request.getLotNo(), companyId);
            pcLotHeadMapper.addLastDetails(pcLotDetails);
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除成型生产号码
     * @param lotNo
     * @param companyId
     */
    private void delPcLotDetailLast(String lotNo, String companyId) {
        pcLotHeadMapper.delLastDetails(lotNo, companyId);
    }

    /**
     * 指令复制
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getLotNoCopy(LotNo2Request request) {
        if (ObjectUtils.isEmpty(request.getLotNo()) || ObjectUtils.isEmpty(request.getNewLotNo())) {
            return ResponseInfo.error("请输入指令!!!");
        }

        //查询指令号码明细是否存在
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
        if (ObjectUtils.isEmpty(codeDetails)) {
            return ResponseInfo.error("指令号码明细未建档!");
        }

        //判断指令是否存在
        Integer queryCount = pcLotHeadMapper.queryCount(request.getNewLotNo(), companyId);
        if (queryCount > 0) {
            return ResponseInfo.error("指令已存在!");
        }

        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        PcLotHead ToCopy = pcLotHeadMapper.selectOne(wrapper);
        PcLotHead Copied = new PcLotHead();
        String userName = UserIdThread.get().getUserName();
        BeanUtil.copyProperties(ToCopy, Copied);
        Copied.setLotNo(request.getNewLotNo());
        Copied.setUserId(userName);
        Copied.setSysDate(LocalDateTime.now());
        Copied.setOrderQty(null);
        Copied.setSurplusQty(null);
        Copied.setStyleType(null);
        Copied.setCustomPo(null);
        Copied.setOrderDate(null);
        Copied.setDeliveryDate(null);
        Copied.setSeason(null);
        Copied.setDevelopmentNo(null);
        Copied.setMSize(null);
        Copied.setProcessUpper(null);
        Copied.setProcessSole(null);
        Copied.setOutFlag(null);
        Copied.setCfmUser(null);
        Copied.setCfmDate(null);
        Copied.setCfmFlag(null);
        Copied.setGenerateUser(null);
        Copied.setGenerateDate(null);
        Copied.setGenerateFlag(null);
        Copied.setCheckUser(null);
        Copied.setCheckDate(null);
        Copied.setCheckFlag(null);
        pcLotHeadMapper.insert(Copied);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 计算中间码
     *
     * @param requests@return
     */
    @Override
    public ResponseInfo getMiddleCode(List<LotNoRequest> requests) {
        if (ObjectUtils.isEmpty(requests)) {
            return ResponseInfo.error("请选择记录!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        for (LotNoRequest request : requests) {
            if (ObjectUtils.isEmpty(request.getLotNo())) {
                return ResponseInfo.error("指令不能为空!");
            }
            if (ObjectUtils.isEmpty(request.getBaseSize())) {
                return ResponseInfo.error("基本码不能为空!");
            }
            //查询是否已检核
            LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                    .eq(PcLotHead::getLotNo, request.getLotNo())
                    .eq(PcLotHead::getCompanyId, companyId);
            PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
            if (ObjectUtils.isEmpty(pcLotHead)){
                return ResponseInfo.error("指令不存在!");
            }
            if ("Y".equals(pcLotHead.getCheckFlag())) {
                return ResponseInfo.error("存在已审核的指令,不能计算中间码!");
            }
            if ("Y".equals(pcLotHead.getCfmFlag())) {
                return ResponseInfo.error("存在已检核的指令,不能计算中间码!");
            }
        }
        for (LotNoRequest request : requests) {
            List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
            if (!ObjectUtils.isEmpty(codeDetails)) {
                String sizeType = pcLotHeadMapper.getSizeType(request.getLotNo(), companyId);
                Map<String, PcLotDetailDto> mapList = new HashMap<>();
                if ("韩码".equals(sizeType)){
                    String baseSize = request.getBaseSize();
                    request.setBaseSize(String.valueOf(Double.valueOf(baseSize)/10));
                    for (PcLotDetailDto codeDetail : codeDetails) {
                        String sizeNo = codeDetail.getSizeNo();
                        double s=Double.valueOf(sizeNo)/10;
                        codeDetail.setSizeNo(String.valueOf(s));
                        mapList.put(codeDetail.getSizeNo(), codeDetail);
                    }
                }else {
                    for (PcLotDetailDto codeDetail : codeDetails) {
                        Map<String, BigDecimal> map = getSizeC();
                        BigDecimal sizeNo = map.get(codeDetail.getSizeNo());
                        if (!ObjectUtils.isEmpty(sizeNo)) {
                            codeDetail.setSizeNo(String.valueOf(sizeNo));
                        }
                        mapList.put(codeDetail.getSizeNo(), codeDetail);
                    }
                }

                //计算权重相加的数量
                var ref = new Object() {
                    BigDecimal count = BigDecimal.ZERO;
                };
                BigDecimal totalQty = codeDetails.stream()
                        .map(PcLotDetailDto::getOrderQty)
                        .reduce(BigDecimal::add)
                        .orElse(BigDecimal.ZERO);
                mapList.forEach(
                        (k, v) -> {
                            //基本码
                            String baseSize = request.getBaseSize();
                            Map<String, BigDecimal> map = getSizeC();
                            BigDecimal sizeNo = map.get(request.getBaseSize());
                            if (!ObjectUtils.isEmpty(sizeNo)) {
                                baseSize = String.valueOf(sizeNo);
                            }
                            int result = baseSize.compareTo(v.getSizeNo());
                            BigDecimal percentage = new BigDecimal(0.05);
                            BigDecimal weight = BigDecimal.ONE;
                            if (result < 0) {
                                //相差的号码数量
                                BigDecimal sum = BigDecimal.valueOf(Double.valueOf(baseSize)).subtract(BigDecimal.valueOf(Double.valueOf(v.getSizeNo())));
                                sum = sum.multiply(percentage).setScale(3, RoundingMode.HALF_UP);
                                percentage = weight.subtract(sum).setScale(3, RoundingMode.HALF_UP);
                                BigDecimal orderQty = percentage.multiply(v.getOrderQty()).setScale(2, RoundingMode.HALF_UP);
                                ref.count = ref.count.add(orderQty);
                            } else if (result > 0) {
                                BigDecimal sum = BigDecimal.valueOf(Double.valueOf(v.getSizeNo())).subtract(BigDecimal.valueOf(Double.valueOf(baseSize)));
                                sum = sum.multiply(percentage).setScale(3, RoundingMode.HALF_UP);
                                percentage = weight.add(sum).setScale(3, RoundingMode.HALF_UP);
                                BigDecimal orderQty = percentage.multiply(v.getOrderQty()).setScale(2, RoundingMode.HALF_UP);
                                ref.count = ref.count.add(orderQty);
                            } else {
                                ref.count = ref.count.add(v.getOrderQty());
                            }
                        }
                );
                BigDecimal percentage = ref.count.divide(totalQty, 3, RoundingMode.HALF_UP);
                String mSize = "";
                if (percentage.compareTo(BigDecimal.valueOf(1)) < 0) {
                    BigDecimal ratio = BigDecimal.valueOf(1).subtract(percentage);
                    BigDecimal num = ratio.divide(BigDecimal.valueOf(0.025),0, RoundingMode.FLOOR);
                    if (num!=null&&num.compareTo(BigDecimal.ZERO)!=0){
                        BigDecimal size = num.multiply(BigDecimal.valueOf(0.5));
                        mSize = getMSize(request.getBaseSize(), size,1);
                    }else {
                        mSize = request.getBaseSize();
                    }
                }else if (percentage.compareTo(BigDecimal.valueOf(1)) > 0){
                    BigDecimal ratio = percentage.subtract(BigDecimal.valueOf(1));
                    BigDecimal num = ratio.divide(BigDecimal.valueOf(0.025),0, RoundingMode.FLOOR);
                    if (num!=null&&num.compareTo(BigDecimal.ZERO)!=0){
                        BigDecimal size = num.multiply(BigDecimal.valueOf(0.5));
                        mSize = getMSize(request.getBaseSize(), size,0);
                    }else {
                        mSize = request.getBaseSize();
                    }
                }else {
                    mSize = request.getBaseSize();
                }
                if ("韩码".equals(sizeType)){
                    double s=Double.valueOf(mSize)*10;
                    mSize=String.valueOf(s);
                }
                pcLotHeadMapper.updateBymSize(request.getLotNo(),mSize,companyId);
            }
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 计算相差的号码
     * @param baseSize
     * @param value
     * @return
     */
    private String getMSize(String baseSize, BigDecimal value,int type) {
        String mSize;
        Map<String, BigDecimal> sizeC = getSizeC();
        BigDecimal size = sizeC.get(baseSize);
        if (type==1) {
            if (!ObjectUtils.isEmpty(size)) {
                BigDecimal s = size.subtract(value);
                mSize = String.valueOf(s);
            } else {
                BigDecimal s = BigDecimal.valueOf(Double.valueOf(baseSize)).subtract(value);
                mSize = String.valueOf(s);
            }
        }else {
            if (!ObjectUtils.isEmpty(size)) {
                BigDecimal s = size.add(value);
                mSize = String.valueOf(s);
            } else {
                BigDecimal s = BigDecimal.valueOf(Double.valueOf(baseSize)).add(value);
                mSize = String.valueOf(s);
            }
        }
        return mSize;
    }

    /**
     * 处理童鞋映射
     * @return
     */
    public Map<String, String>  getCSize(){
        Map<String, String> map = new HashMap<>();
        map.put("0.5","C13.5");
        map.put("0","C13");
        map.put("-0.5","C12.5");
        map.put("-1","C12");
        map.put("-1.5","C11.5");
        map.put("-2","C11");
        map.put("-2.5","C10.5");
        map.put("-3","C10");
        return map;
    }
    /**
     * 0检核/1取消检核
     * @param requests
     * @param choose
     * @return
     */
    @Override
    public ResponseInfo getLotNoCheck(List<LotNoRequest> requests, Integer choose) {
        if (ObjectUtils.isEmpty(requests)){
            return ResponseInfo.error("请选择记录!");
        }
        for (LotNoRequest request : requests) {
            if (ObjectUtils.isEmpty(request.getLotNo())){
                return ResponseInfo.error("指令不能为空!");
            }
            //查询是否已检核
            String companyId = UserIdThread.get().getCompanyId();
            LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                    .eq(PcLotHead::getLotNo, request.getLotNo())
                    .eq(PcLotHead::getCompanyId, companyId);
            PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
            if (ObjectUtils.isEmpty(pcLotHead)){
                return ResponseInfo.error("无效指令信息!");
            }
            String flag = pcLotHead.getCfmFlag();
            switch (choose){
                case 0:
                    if (!ObjectUtils.isEmpty(flag)){
                        if (flag.equals(DefineEnum.CHECKOUT_FLAG.getValue())){
                            return ResponseInfo.error("指令:"+pcLotHead.getLotNo()+"已经检核!");
                        }
                    }
                    if (ObjectUtils.isEmpty(pcLotHead.getMSize())){
                        return ResponseInfo.error("中间码为空!");
                    }
                    Integer count = pcLotHeadMapper.getPcLotUsages(pcLotHead.getLotNo(), companyId);
                    if (count==null||count==0){
                        return ResponseInfo.error("指令:"+pcLotHead.getLotNo()+"未生成指令用量明细,不能检核!");
                    }
                    String userName = UserIdThread.get().getUserName();
                    String cfmFlag = DefineEnum.CHECKOUT_FLAG.getValue();
                    pcLotHeadMapper.updateLotNoCheckOut(request.getLotNo(),companyId,userName,cfmFlag,LocalDateTime.now());
                    break;
                case 1:
                    if (!ObjectUtils.isEmpty(pcLotHead.getCheckFlag())){
                        return ResponseInfo.error("指令:"+pcLotHead.getLotNo()+"已经审核,不能取消检核!");
                    }
                    if (ObjectUtils.isEmpty(flag)) {
                        return ResponseInfo.error("指令:"+pcLotHead.getLotNo()+"未检核,不能取消检核!!");
                    }
                    pcLotHeadMapper.updateLotNoCheckOut(request.getLotNo(), companyId,null, null, null);
                    break;
                default:
                    return ResponseInfo.error("参数错误!");
            }
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 指令明细修改
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleDetailUpdate(StyleDetailUpdateRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        //查询是否已检核
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> query = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        PcLotHead  object= pcLotHeadMapper.selectOne(query);
        if (ObjectUtils.isEmpty(object)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        if ("Y".equals(object.getCheckFlag())){
            return ResponseInfo.error("该指令已审核不能修改!");
        }
        if ("Y".equals(object.getCfmFlag())){
            return ResponseInfo.error("该指令已检核不能修改!");
        }
        PcLotHead pcLotHead = BeanUtil.copyBean(request, PcLotHead.class);
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>().eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        pcLotHeadMapper.update(pcLotHead,wrapper);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * po号码添加
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getPoNumberDetailAdd(PoNumberAddRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }

        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> query = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        PcLotHead  object= pcLotHeadMapper.selectOne(query);
        if (ObjectUtils.isEmpty(object)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        if ("Y".equals(object.getCheckFlag())){
            return ResponseInfo.error("该指令已审核不能操作!");
        }
        if ("Y".equals(object.getCfmFlag())){
            return ResponseInfo.error("该指令已检核不能操作!");
        }
        PcLotGroup pcLotGroup = BeanUtil.copyBean(request, PcLotGroup.class);
        pcLotGroup.setCompanyId(companyId);
        pcLotGroup.setSizeNotice(request.getSizeCode());

        Integer queryCount = pcLotHeadMapper.getPoNumberDetail(request.getGroupNo(), request.getLotNo(), companyId);
        if (queryCount > 0) {
            pcLotHeadMapper.updatePoNumberDetail(pcLotGroup);
        } else {
            pcLotHeadMapper.addPoNumberDetail(pcLotGroup);
        }

        if (!ObjectUtils.isEmpty(request.getNumberList())) {
            List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
            ArrayList<PcLotDetail> pcLotDetailList = new ArrayList<>();
            if (ObjectUtils.isEmpty(codeDetails)) {
                for (PoNumberRequest poNumberRequest : request.getNumberList()) {
                        PcLotDetail pcLotDetail = new PcLotDetail();
                        pcLotDetail.setCompanyId(companyId);
                        pcLotDetail.setLotNo(request.getLotNo());
                        pcLotDetail.setSizeNo(poNumberRequest.getSizeNo());
                        pcLotDetail.setSeqNo(poNumberRequest.getSeqNo());
                        pcLotDetail.setOrderQty(Float.valueOf(poNumberRequest.getOrderQty()));
                        pcLotDetailList.add(pcLotDetail);
                }
                if (!ObjectUtils.isEmpty(pcLotDetailList)){
                    pcLotHeadMapper.addPcLotDetail(pcLotDetailList);
                }
            }else {
                Set<String> sizeNoSet = new HashSet<>();
                for (PcLotDetailDto codeDetail : codeDetails) {
                    sizeNoSet.add(codeDetail.getSizeNo());
                }
                for (PoNumberRequest poNumberRequest : request.getNumberList()) {
                    if (!sizeNoSet.contains(poNumberRequest.getSizeNo())) {
                        PcLotDetail pcLotDetail = new PcLotDetail();
                        pcLotDetail.setCompanyId(companyId);
                        pcLotDetail.setLotNo(request.getLotNo());
                        pcLotDetail.setSizeNo(poNumberRequest.getSizeNo());
                        pcLotDetail.setSeqNo(poNumberRequest.getSeqNo());
                        pcLotDetail.setOrderQty(Float.valueOf(poNumberRequest.getOrderQty()));
                        pcLotDetailList.add(pcLotDetail);
                    }
                }
                if (!ObjectUtils.isEmpty(pcLotDetailList)){
                   pcLotHeadMapper.addPcLotDetail(pcLotDetailList);
                }

                List<PoNumberRequest> numberList = request.getNumberList();
                numberList.forEach(t -> {
                    if (t.getOrderQty() == null) {
                        t.setOrderQty(0);
                    }
                });
                List<PoNumberRequest> delList = numberList.stream()
                        .filter(t -> t.getOrderQty() == 0)
                        .collect(Collectors.toList());
                List<PoNumberRequest> updateList = request.getNumberList().stream()
                        .filter(t -> t.getOrderQty()>0)
                        .collect(Collectors.toList());

                if (!ObjectUtils.isEmpty(delList)) {
                    pcLotHeadMapper.delPcLotDetail(request.getLotNo(),companyId, delList);
                }
                if (!ObjectUtils.isEmpty(updateList)) {
                    pcLotHeadMapper.updatePcLotDetail(request.getLotNo(),companyId, updateList);
                }
            }
            pcLotHeadMapper.delPcLotDetail2(request.getLotNo(),companyId);
            updateByCount(request.getLotNo(), companyId);
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 修改订单数量与预补数量
     * @param lotNo
     * @param companyId
     */
    private void updateByCount(String lotNo, String companyId) {
        //查询总数量
        PcLotHeadCountDto sum = pcLotHeadMapper.getCodeDetailsSum(lotNo, companyId);
        if (!ObjectUtils.isEmpty(sum)){
            sum.setZero();
            pcLotHeadMapper.updateOrderQty(lotNo,sum.getOrderCount(),sum.getSurplusCount(),companyId);
        }
    }

    /**
     * po号码删除
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getPoNumberDetailDel(PoNumberDelRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())||ObjectUtils.isEmpty(request.getGroupNo())){
            return ResponseInfo.error("指令和配码不能为空!");
        }

        //删除
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> query = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        PcLotHead  object= pcLotHeadMapper.selectOne(query);
        if (ObjectUtils.isEmpty(object)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        if ("Y".equals(object.getCheckFlag())){
            return ResponseInfo.error("该指令已审核不能删除!");
        }
        if ("Y".equals(object.getCfmFlag())){
            return ResponseInfo.error("该指令已检核不能删除!");
        }
        pcLotHeadMapper.delPcLotGroup(request.getLotNo(),request.getGroupNo(),companyId);
        if (!ObjectUtils.isEmpty(request.getNumberList())){
            List<PoNumberRequest> numberList = request.getNumberList();
            numberList.forEach(t -> {
                if (t.getOrderQty() == null) {
                    t.setOrderQty(0);
                }
            });
            List<PoNumberRequest> delList = numberList.stream()
                    .filter(t -> t.getOrderQty() == 0)
                    .collect(Collectors.toList());
            List<PoNumberRequest> updateList = request.getNumberList().stream()
                    .filter(t -> t.getOrderQty()>0)
                    .collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(delList)){
                pcLotHeadMapper.delPcLotDetail(request.getLotNo(), companyId, delList);
            }
            if (!ObjectUtils.isEmpty(updateList)){
                pcLotHeadMapper.updatePcLotDetail(request.getLotNo(), companyId, updateList);
            }
            updateByCount(request.getLotNo(), companyId);
        }
        return ResponseInfo.ok("操作成功!");
    }

    @Resource
    private LargeCargoUsageMapper largeCargoUsageMapper;

    /**
     * 生成指令单
     * @param requests
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getUsageGenerate(List<LotNo2Request> requests) {
        if (ObjectUtils.isEmpty(requests)){
            return ResponseInfo.error("请选择记录!");
        }
        for (LotNo2Request request : requests) {
            if (ObjectUtils.isEmpty(request.getLotNo())) {
                return ResponseInfo.error("指令不能为空!");
            }
            if (ObjectUtils.isEmpty(request.getBaseSize())) {
                return ResponseInfo.error("基本码不能为空!");
            }
            String companyId = UserIdThread.get().getCompanyId();
            LambdaQueryWrapper<PcLotHead> query = new LambdaQueryWrapper<PcLotHead>()
                    .eq(PcLotHead::getLotNo, request.getLotNo())
                    .eq(PcLotHead::getCompanyId, companyId);
            PcLotHead pcLotHead = pcLotHeadMapper.selectOne(query);
            if (ObjectUtils.isEmpty(pcLotHead)){
                return ResponseInfo.error("指令不存在!");
            }
            if ("Y".equals(pcLotHead.getCheckFlag())){
                return ResponseInfo.error(pcLotHead.getLotNo() + "指令已审核!");
            }
            if ("Y".equals(pcLotHead.getCfmFlag())){
                return ResponseInfo.error(pcLotHead.getLotNo()+"指令已检核!");
            }
            if (ObjectUtils.isEmpty(pcLotHead.getMSize())) {
                return ResponseInfo.error(request.getLotNo() + "指令无中间码!");
            }
            if (ObjectUtils.isEmpty(pcLotHead.getOrderQty()) || pcLotHead.getOrderQty() == 0) {
                return ResponseInfo.error(request.getLotNo() + "指令订单量为空或0!");
            }
            if (ObjectUtils.isEmpty(pcLotHead.getMoldNo())) {
                return ResponseInfo.error(request.getLotNo() + "指令单底模未输入!");
            }
            if (ObjectUtils.isEmpty(pcLotHead.getLastNo())) {
                return ResponseInfo.error(request.getLotNo() + "指令单楦头未输入!");
            }
            List<PcLotDetailDto> codeDetails = pcLotHeadMapper.getCodeDetails(request.getLotNo(), companyId);
            if (ObjectUtils.isEmpty(codeDetails)) {
                return ResponseInfo.error(request.getLotNo() + "指令号码明细未建档!");
            }

            SdBomHeadNew2 sdBomHeadNew2 = largeCargoUsageMapper.sdBomHeadNew2(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            if (sdBomHeadNew2 == null || ObjectUtils.isEmpty(sdBomHeadNew2.getCfmFlag())) {
                return ResponseInfo.error(request.getLotNo() + "指令型体配色BOM资料未检核!");
            }
            //查询bom资料
            List<YfBomPartNew2Dto> usageList = largeCargoUsageMapper.getDevelopBomUsageList(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            if (ObjectUtils.isEmpty(usageList)) {
                return ResponseInfo.error(request.getLotNo() + "指令未找到bom资料!");
            }

            //判断计算方式和用量是否为空
            int usageTypeCount = 0;
            int usageCount = 0;
            for (YfBomPartNew2Dto dto : usageList) {
                if (ObjectUtils.isEmpty(dto.getUsageType())) {
                    usageTypeCount++;
                }
                if (ObjectUtils.isEmpty(dto.getUsage())) {
                    usageCount++;
                }
            }
            if (usageTypeCount > 0) {
                return ResponseInfo.error("指令" + request.getLotNo() + "BOM有" + usageTypeCount + "个计算方式为空的记录!");
            }
            if (usageCount > 0) {
                return ResponseInfo.error("指令" + request.getLotNo() + "BOM有" + usageCount + "个用量为空的记录!");
            }

            String sizeType = pcLotHeadMapper.getSizeType(request.getLotNo(), companyId);
            if ("韩码".equals(sizeType)){
                String baseSize = request.getBaseSize();
                request.setBaseSize(String.valueOf(Double.valueOf(baseSize)/10));
                String mSize = pcLotHead.getMSize();
                pcLotHead.setMSize(String.valueOf(Double.valueOf(mSize)/10));
                for (PcLotDetailDto codeDetail : codeDetails) {
                    String sizeNo = codeDetail.getSizeNo();
                    double s=Double.valueOf(sizeNo)/10;
                    codeDetail.setSizeNo(String.valueOf(s));
                }
            }else {
                //处理童鞋
                for (PcLotDetailDto codeDetail : codeDetails) {
                    Map<String, BigDecimal> map = getSizeC();
                    BigDecimal sizeNo = map.get(codeDetail.getSizeNo());
                    if (!ObjectUtils.isEmpty(sizeNo)){
                        codeDetail.setSizeNo(String.valueOf(sizeNo));
                    }
                }
            }


            //生成指令单
            Float totalQty = pcLotHead.getTotalQty();
            List<PcLotUsage> pcLotUsageList = new ArrayList<>();
            for (YfBomPartNew2Dto s : usageList) {
                PcLotUsage pcLotUsage = new PcLotUsage();
                BeanUtil.copyProperties(s, pcLotUsage);
                String typeNo = PartServiceImpl.getTypeNo(s.getMtlNo());
                pcLotUsage.setMtlTypeNo(typeNo);
                pcLotUsage.setCompanyId(companyId);
                pcLotUsage.setLotNo(request.getLotNo());
                if ("韩码".equals(sizeType)){
                    if (!ObjectUtils.isEmpty(s.getSize1())){
                        double s1 =Double.valueOf(s.getSize1())/10;
                        s.setSize1(String.valueOf(s1));
                    }
                    if (!ObjectUtils.isEmpty(s.getSize2())){
                        double s2 =Double.valueOf(s.getSize2())/10;
                        s.setSize2(String.valueOf(s2));
                    }
                }

                //处理基本码
                if (s.getUsageType().equals("B")) {
                    //处理尺码
                    if (!ObjectUtils.isEmpty(s.getSize1()) && !ObjectUtils.isEmpty(s.getSize2())) {
                        BigDecimal size1 = new BigDecimal(s.getSize1());
                        BigDecimal size2 = new BigDecimal(s.getSize2());
                        if (size2.compareTo(size1) < 0) {
                            throw new ServiceErrorException("尺码起大于尺码止号码!");
                        }
                        BigDecimal orderQty = codeDetails.stream()
                                .filter(dto -> {
                                    BigDecimal dtoSize = new BigDecimal(dto.getSizeNo());
                                    return size1.compareTo(dtoSize) <= 0 && size2.compareTo(dtoSize) >= 0;
                                })
                                .map(dto -> {
                                    return  dto.getOrderQty() != null ? dto.getOrderQty() : BigDecimal.ZERO;
                                })
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal ttlUsage = orderQty.multiply(s.getUsage()).setScale(1, BigDecimal.ROUND_HALF_UP);
                        pcLotUsage.setStdUsage(pcLotUsage.getUsage());
                        pcLotUsage.setSumUsage(ttlUsage);
                        ttlUsage = getUsage(ttlUsage);
                        pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                    }else if (ObjectUtils.isEmpty(s.getSize1()) && ObjectUtils.isEmpty(s.getSize2())){
                        BigDecimal orderQty;
                        //处理扣子类、线类
                        if (s.getMtlNo().startsWith("J1") || s.getMtlNo().startsWith("F3")) {
                            orderQty = getOrderQtyToSurplusQtyByCount(codeDetails);
                        } else {
                            orderQty = getOrderQtyCount(codeDetails);
                        }

                        BigDecimal ttlUsage = orderQty.multiply(s.getUsage()).setScale(1, BigDecimal.ROUND_HALF_UP);
                        pcLotUsage.setStdUsage(pcLotUsage.getUsage());
                        pcLotUsage.setSumUsage(ttlUsage);
                        ttlUsage = getUsage(ttlUsage);
                        pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                    }else {
                        return ResponseInfo.error("数据异常,分段号码必须同时存在!");
                    }
                } else if (s.getUsageType().equals("F")) {
                    //处理全码
                    List<SdBomUsageNew2> sdBomUsageNew2List = pcLotHeadMapper.getSdBomUsageNew2(pcLotHead.getStyle(), pcLotHead.getColor(), s.getPartName(), s.getSegment(),companyId);
                    if (ObjectUtils.isEmpty(sdBomUsageNew2List)) {
                        return ResponseInfo.error("指令:" + request.getLotNo() + ",部位:" + s.getPartName() + ",全码用量不完整!");
                    }
                    if ("韩码".equals(sizeType)){
                        for (SdBomUsageNew2 sdBomUsageNew2 : sdBomUsageNew2List) {
                            double sizeNo=Double.valueOf(sdBomUsageNew2.getSizeFrom())/10;
                            sdBomUsageNew2.setSizeFrom(String.valueOf(sizeNo));
                        }
                    }
                    List<String> sizeNos = codeDetails.stream()
                            .map(PcLotDetailDto::getSizeNo)
                            .distinct()
                            .collect(Collectors.toList());
                    boolean exists = sizeNos.stream()
                            .allMatch(size -> sdBomUsageNew2List.stream()
                                    .map(SdBomUsageNew2::getSizeFrom)
                                    .anyMatch(size::equals));
                    if (!exists) {
                        return ResponseInfo.error("指令:" + request.getLotNo() + ",部位:" + s.getPartName() + ",全码用量不完整!");
                    }

                    //计算全码用量
                    BigDecimal ttlUsage = BigDecimal.ZERO;
                    for (SdBomUsageNew2 sdBomUsageNew2 : sdBomUsageNew2List) {
                        for (PcLotDetailDto codeDetail : codeDetails) {
                            if (codeDetail.getSizeNo().equals(sdBomUsageNew2.getSizeFrom())) {
                                BigDecimal qty = codeDetail.getTotalQty();
                                BigDecimal count = qty.multiply(sdBomUsageNew2.getMtlUsage());
                                ttlUsage = ttlUsage.add(count);
                            }
                        }
                    }
                    BigDecimal std = ttlUsage.divide(BigDecimal.valueOf(totalQty), 5,RoundingMode.HALF_UP);
                    pcLotUsage.setStdUsage(std);
                    pcLotUsage.setSumUsage(ttlUsage);
                    ttlUsage = getUsage(ttlUsage);
                    pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                } else {
                    if (!ObjectUtils.isEmpty(s.getSize1()) && !ObjectUtils.isEmpty(s.getSize2())) {
                        BigDecimal size1 = new BigDecimal(s.getSize1());
                        BigDecimal size2 = new BigDecimal(s.getSize2());
                        if (size2.compareTo(size1) < 0) {
                            throw new ServiceErrorException("尺码起大于尺码止号码!");
                        }
                        BigDecimal orderQty = codeDetails.stream()
                                .filter(dto -> {
                                    BigDecimal dtoSize = new BigDecimal(dto.getSizeNo());
                                    return size1.compareTo(dtoSize) <= 0 && size2.compareTo(dtoSize) >= 0;
                                })
                                .map(dto -> {
                                    return  dto.getTotalQty() != null ? dto.getTotalQty() : BigDecimal.ZERO;
                                })
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal ttlUsage = orderQty.multiply(s.getUsage()).setScale(1, BigDecimal.ROUND_HALF_UP);
                        pcLotUsage.setStdUsage(pcLotUsage.getUsage());
                        pcLotUsage.setSumUsage(ttlUsage);
                        ttlUsage = getUsage(ttlUsage);
                        pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                    }else if (ObjectUtils.isEmpty(s.getSize1())&& ObjectUtils.isEmpty(s.getSize2())){
                        //处理大底
                        if (!s.getMtlNo().startsWith("L")) {
                            //处理中间码
                            int result = pcLotHead.getMSize().compareTo(request.getBaseSize());
                            if (result < 0) {
                                //相差的号码数
                                BigDecimal sum = BigDecimal.valueOf(Double.parseDouble(request.getBaseSize())).subtract(BigDecimal.valueOf(Double.parseDouble(pcLotHead.getMSize())));
                                //要减去的值
                                BigDecimal size = sum.multiply(s.getUsage()).multiply(new BigDecimal(0.05));
                                BigDecimal usage = s.getUsage().subtract(size);
                                BigDecimal ttlUsage = usage.multiply(BigDecimal.valueOf(totalQty));
                                pcLotUsage.setStdUsage(usage.setScale(5, RoundingMode.HALF_UP));
                                pcLotUsage.setSumUsage(ttlUsage.setScale(5, RoundingMode.HALF_UP));
                                ttlUsage = getUsage(ttlUsage);
                                pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                            } else if (result > 0) {
                                //相差的号码数
                                BigDecimal sum = BigDecimal.valueOf(Double.parseDouble(pcLotHead.getMSize())).subtract(BigDecimal.valueOf(Double.parseDouble(request.getBaseSize())));
                                //要加上的值
                                BigDecimal size = sum.multiply(s.getUsage()).multiply(new BigDecimal(0.05));
                                BigDecimal usage = s.getUsage().add(size);
                                BigDecimal ttlUsage = usage.multiply(BigDecimal.valueOf(totalQty));
                                pcLotUsage.setStdUsage(usage.setScale(5, RoundingMode.HALF_UP));
                                pcLotUsage.setSumUsage(ttlUsage.setScale(5, RoundingMode.HALF_UP));
                                ttlUsage = getUsage(ttlUsage);
                                pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                            } else {
                                BigDecimal ttlUsage = BigDecimal.valueOf(totalQty).multiply(s.getUsage());
                                pcLotUsage.setStdUsage(pcLotUsage.getUsage());
                                pcLotUsage.setSumUsage(ttlUsage.setScale(5, RoundingMode.HALF_UP));
                                ttlUsage = getUsage(ttlUsage);
                                pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                            }
                        } else {
                            BigDecimal orderQty = getOrderQtyCount(codeDetails);
                            BigDecimal ttlUsage = orderQty.multiply(s.getUsage()).setScale(1, BigDecimal.ROUND_HALF_UP);
                            pcLotUsage.setStdUsage(pcLotUsage.getUsage());
                            pcLotUsage.setSumUsage(ttlUsage);
                            ttlUsage = getUsage(ttlUsage);
                            pcLotUsage.setTtlUsage(Float.valueOf(String.valueOf(ttlUsage)));
                        }
                    }else {
                        return ResponseInfo.warn("数据异常,分段号码必须同时存在!");
                    }
                }
                pcLotUsageList.add(pcLotUsage);
            }

            String userName = UserIdThread.get().getUserName();
            pcLotHead.setGenerateUser(userName);
            pcLotHead.setGenerateDate(LocalDateTime.now());
            pcLotHead.setGenerateFlag("Y");
            if ("韩码".equals(sizeType)) {
                String mSize = pcLotHead.getMSize();
                double s=Double.valueOf(mSize)*10;
                pcLotHead.setMSize(String.valueOf(s));
            }
            LambdaUpdateWrapper<PcLotHead> updateWrapper = new LambdaUpdateWrapper<PcLotHead>().eq(PcLotHead::getLotNo, request.getLotNo())
                    .eq(PcLotHead::getCompanyId,companyId);
            pcLotHeadMapper.update(pcLotHead, updateWrapper);
            pcLotHeadMapper.delPcLotUsage(request.getLotNo(),companyId);
            PcLotUsageHead lotUsageHead = new PcLotUsageHead();
            lotUsageHead.setCompanyId(companyId);
            lotUsageHead.setLotNo(pcLotHead.getLotNo());
            lotUsageHead.setUserId(UserIdThread.get().getLoginName());
            lotUsageHead.setSysDate(LocalDateTime.now());
            lotUsageHead.setMidSize(pcLotHead.getMSize());
            pcLotHeadMapper.addPcLotUsageHead(lotUsageHead);
            pcLotHeadMapper.addPcLotUsageList(pcLotUsageList);

            //处理子材料
            List<PcLotUsageFit> sdBomFitSubList = pcLotHeadMapper.getSdBomFitSubList(pcLotHead.getStyle(), pcLotHead.getColor(),companyId);
            if (!ObjectUtils.isEmpty(sdBomFitSubList)){
                for (PcLotUsageFit sdBomFitSub : sdBomFitSubList) {
                    for (PcLotUsage pcLotUsage : pcLotUsageList) {
                        if (sdBomFitSub.getMtlNo().equals(pcLotUsage.getMtlNo())&&sdBomFitSub.getPartName().equals(pcLotUsage.getPartName())&&
                        sdBomFitSub.getSegment().equals(pcLotUsage.getSegment())){
                            sdBomFitSub.setLotNo(request.getLotNo());
                            sdBomFitSub.setCompanyId(companyId);
                            sdBomFitSub.setMtlTypeNo(pcLotUsage.getMtlTypeNo());
                            sdBomFitSub.setSubMtlTypeNo(PartServiceImpl.getTypeNo(sdBomFitSub.getSubMtlNo()));
                            BigDecimal percent = sdBomFitSub.getPercent().setScale(5, RoundingMode.HALF_UP);
                            sdBomFitSub.setTtlUsage(BigDecimal.valueOf(pcLotUsage.getTtlUsage()).setScale(1, RoundingMode.HALF_UP));
                            sdBomFitSub.setSubTtlUsage(getUsage(BigDecimal.valueOf(pcLotUsage.getTtlUsage()).multiply(percent).setScale(1, RoundingMode.HALF_UP)));
                        }
                    }
                }
                pcLotHeadMapper.delPcLotUsageFit(request.getLotNo(),companyId);
                pcLotHeadMapper.addPcLotUsageFit(sdBomFitSubList);
            }
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 判断小数点后面小于5，返回整数部分加0.5，否则向上取整
     * @param usage
     * @return
     */
    private BigDecimal getUsage(BigDecimal usage) {
        BigDecimal scaledUsage = usage.setScale(1, RoundingMode.HALF_UP);
        // 获取小数点后第一位
        BigDecimal firstDecimal = scaledUsage.remainder(BigDecimal.ONE).movePointRight(1);
        // 如果小数点后小于5，返回整数部分加0.5
        if (firstDecimal.compareTo(BigDecimal.ZERO) > 0 && firstDecimal.compareTo(new BigDecimal("5")) < 0) {
            return scaledUsage.setScale(0, RoundingMode.DOWN).add(new BigDecimal("0.5"));
        } else if (firstDecimal.compareTo(new BigDecimal("5")) == 0){
            return scaledUsage;
        }else{
            // 向上取整
            return scaledUsage.setScale(0, RoundingMode.CEILING);
        }
    }

    /**
     * 计算订单数量
     * @param codeDetails
     * @return
     */
    private static @NotNull BigDecimal getOrderQtyCount(List<PcLotDetailDto> codeDetails) {
        BigDecimal orderQty = codeDetails.stream()
                .map(dto -> {
                    BigDecimal ordQty=dto.getOrderQty() != null ? dto.getOrderQty() : BigDecimal.ZERO;
                    return ordQty;
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return orderQty;
    }

    /**
     * 计算订单数加预补数量
     * @param codeDetails
     * @return
     */
    private static @NotNull BigDecimal getOrderQtyToSurplusQtyByCount(List<PcLotDetailDto> codeDetails) {
        BigDecimal orderQty = codeDetails.stream()
                .map(dto -> {
                    BigDecimal ordQty=dto.getOrderQty() != null ? dto.getOrderQty() : BigDecimal.ZERO;
                    BigDecimal surplusQty=dto.getSurplusQty() != null ? dto.getSurplusQty() : BigDecimal.ZERO;
                    return ordQty.add(surplusQty);
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return orderQty;
    }

    /**
     * 处理童鞋号码
     * @return
     */
    public Map<String, BigDecimal>  getSizeC(){
        Map<String, BigDecimal> map = new HashMap<>();
            map.put("C13.5", BigDecimal.valueOf(0.5));
            map.put("C13", BigDecimal.valueOf(0));
            map.put("C12.5", BigDecimal.valueOf(-0.5));
            map.put("C12", BigDecimal.valueOf(-1));
            map.put("C11.5", BigDecimal.valueOf(-1.5));
            map.put("C11", BigDecimal.valueOf(-2));
            map.put("C10.5", BigDecimal.valueOf(-2.5));
            map.put("C10", BigDecimal.valueOf(-3));
            return map;
    }

    /**
     * 指令明细配码修改
     * @param requests
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getStyleSizeDataUpdate(List<PcLotDetailUpdateRequest> requests) {
        if (ObjectUtils.isEmpty(requests)){
            return ResponseInfo.error("数据不能为空!");
        }
        for (PcLotDetailUpdateRequest request:requests) {
            if (ObjectUtils.isEmpty(request.getLotNo())||ObjectUtils.isEmpty(request.getSizeNo())){
                return ResponseInfo.error("指令和号码不能为空!");
            }
            request.setCompanyId(UserIdThread.get().getCompanyId());
        }
        LambdaQueryWrapper<PcLotHead> query = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, requests.get(0).getLotNo())
                .eq(PcLotHead::getCompanyId, UserIdThread.get().getCompanyId());
        PcLotHead  object= pcLotHeadMapper.selectOne(query);
        if (ObjectUtils.isEmpty(object)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        if ("Y".equals(object.getCheckFlag())){
            return ResponseInfo.error("该指令已审核不能修改!");
        }
        if ("Y".equals(object.getCfmFlag())){
            return ResponseInfo.error("该指令已检核不能修改!");
        }
        for (PcLotDetailUpdateRequest request : requests) {
            pcLotHeadMapper.updatePcLotDetailSurplus(request);
        }
        updateByCount(requests.get(0).getLotNo(), UserIdThread.get().getCompanyId());
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 下拉框返回数据
     * @return
     */
    @Override
    public ResponseInfo getCondition() {
        HashMap<String, Object> map = new HashMap<>();
        String companyId = UserIdThread.get().getCompanyId();
        List<StyleDetailDto> styleToDetail = pcLotHeadMapper.getStyleToDetail(companyId);
        List<String> custom = pcLotHeadMapper.getCustom(companyId);
        List<String> cutNo = pcLotHeadMapper.getCutNo(companyId);
        List<String> laseNo = pcLotHeadMapper.getLaseNo(companyId);
        List<String> moldNo = pcLotHeadMapper.getMoldNo(companyId);
        List<String> soleVendor = pcLotHeadMapper.getSoleVendor(companyId);
        List<String> season = pcLotHeadMapper.getSeason(companyId);
        map.put("styleToDetail",styleToDetail);
        map.put("custom",custom);
        map.put("cutNo",cutNo);
        map.put("lastNo",laseNo);
        map.put("moldNo",moldNo);
        map.put("soleVendor",soleVendor);
        map.put("season",season);
        return ResponseInfo.ok(map);
    }

    /**
     * 根据型体回显数据
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleCondition(LotNoRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        StyleDataDto dataDto = pcLotHeadMapper.getStyleCondition(request.getStyle(),companyId);
        return ResponseInfo.ok(dataDto);
    }

    /**
     * 外包指令输入-新增指令
     * @param request
     * @return
     */
    @Override
    public ResponseInfo addLotNo(PcLotHeadRequest request) {
        if (request.getLotNo().isEmpty()){
            return ResponseInfo.error("指令为空!");
        }
        if (!request.getLotNo().startsWith("WB")) {
            return ResponseInfo.error("外包指令前面需要添加：WB!!!");
        }
        if (request.getStyle().isEmpty()){
            return ResponseInfo.error("型体为空!");
        }
        if (request.getStyleType().isEmpty()){
            return ResponseInfo.error("新旧型体为空!");
        }
        if (request.getColor().isEmpty()){
            return ResponseInfo.error("颜色为空!");
        }
        if (request.getOrderStartDate()==null){
            return ResponseInfo.error("下单日期为空!");
        }
        if (request.getCustomPo().isEmpty()){
            return ResponseInfo.error("合同号为空!");
        }
        if (request.getDeliveryStartDate()==null){
            return ResponseInfo.error("客人交期为空!");
        }
        //判断指令是否存在
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo,request.getLotNo());
        PcLotHead head = pcLotHeadMapper.selectOne(wrapper);
        if (head!=null){
            return ResponseInfo.error("指令已存在!");
        }
        PcLotHead pcLotHead = new PcLotHead();
        BeanUtil.copyProperties(request,pcLotHead);
        String userName = UserIdThread.get().getUserName();
        pcLotHead.setUserId(userName);
        pcLotHead.setSysDate(LocalDateTime.now());
        pcLotHead.setCompanyId(companyId);
        pcLotHead.setDeliveryDate(request.getDeliveryStartDate());
        pcLotHead.setOrderDate(request.getOrderStartDate());
        pcLotHead.setProcessAll(DefineEnum.CHECKOUT_FLAG.getValue());
        pcLotHead.setLacing(DefineEnum.CHECKOUT_FLAG_N.getValue());
        pcLotHeadMapper.insert(pcLotHead);
        return ResponseInfo.ok("操作成功!");
    }

    @Resource
    private PcLotExp2Mapper pcLotExp2Mapper;

    @Resource
    private PcLotExp2ServiceImpl pcLotExp2Service;

    /**
     * 0审核/1取消审核
     * @param requests
     * @param choose
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getLotNoCheckUp(List<LotNoCheckRequest> requests, Integer choose) {
        if (ObjectUtils.isEmpty(requests)){
            return ResponseInfo.error("请选择记录!");
        }
        for (LotNoCheckRequest request : requests) {
            if (ObjectUtils.isEmpty(request.getLotNo())){
                return ResponseInfo.error("指令不能为空!");
            }
            //查询是否已审核
            String companyId = UserIdThread.get().getCompanyId();
            String userName = UserIdThread.get().getUserName();
            LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                    .eq(PcLotHead::getLotNo, request.getLotNo())
                    .eq(PcLotHead::getCompanyId, companyId);
            PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
            if (ObjectUtils.isEmpty(pcLotHead)){
                return ResponseInfo.error("指令不存在!");
            }
            if (!"Y".equals(pcLotHead.getCfmFlag())){
                return ResponseInfo.error("存在指令未检核!");
            }
            //查询版本日志
            Integer version = pcLotExp2Mapper.getLotNoExist(request.getLotNo(),companyId);
            //指令材料用量
            List<PcLotUsage> lotUsageList = pcLotHeadMapper.getPcLotUsageList(request.getLotNo(), companyId);
            //指令子材料用量
            List<PcLotUsageFit> lotUsageFitList = pcLotHeadMapper.getPcLotUsageFitList(request.getLotNo(), companyId);
            List<PcLotUsageChg> pcLotUsageChgList=new ArrayList<>();
            List<PcLotUsageFitChg> pcLotUsageChgFitList=new ArrayList<>();
            switch (choose){
                case 0:
                    if (!ObjectUtils.isEmpty(pcLotHead.getCheckFlag())){
                        if (pcLotHead.getCheckFlag().equals(DefineEnum.CHECKOUT_FLAG.getValue())){
                            return ResponseInfo.error("该指令已审核!");
                        }
                    }
                    Integer count = pcLotHeadMapper.getPcLotUsages(pcLotHead.getLotNo(), companyId);
                    if (count==null||count==0){
                        return ResponseInfo.error("指令:"+pcLotHead.getLotNo()+"未生成指令用量明细,不能审核!");
                    }
                    String CheckFlag = DefineEnum.CHECKOUT_FLAG.getValue();
                    pcLotHeadMapper.updateLotNoCheckUp(request.getLotNo(),companyId,userName,CheckFlag,LocalDateTime.now());
                    if (version!=0) {
                        //指令用量差异明细
                        List<PcLotUsageChg> usageChgList = pcLotExp2Mapper.getPcLotUsageChgList(request.getLotNo(), companyId, version);
                        //子材料用量差异明细
                        List<PcLotUsageFitChg> lotUsageFitChgList = pcLotExp2Mapper.getPcLotUsageFitChgList(request.getLotNo(), companyId, version);
                        for (PcLotUsage pcLotUsage : lotUsageList) {
                            boolean found = false;
                            for (PcLotUsageChg pcLotUsageChg : usageChgList) {
                                //现用量
                                BigDecimal ttlUsage = pcLotUsage.getTtlUsage()!=null? BigDecimal.valueOf(pcLotUsage.getTtlUsage()) :BigDecimal.ZERO;
                                BigDecimal ttlUsagePre = pcLotUsageChg.getTtlUsagePre()!=null?pcLotUsageChg.getTtlUsagePre() :BigDecimal.ZERO;
                                if (pcLotUsage.getMtlNo().equals(pcLotUsageChg.getMtlNo())&&
                                        pcLotUsage.getPartName().equals(pcLotUsageChg.getPartName())&&
                                        pcLotUsage.getSeqNo().equals(pcLotUsageChg.getSeqNo())){
                                    if (ttlUsage.compareTo(ttlUsagePre) > 0) {
                                        pcLotUsageChg.setRemark("用量增加");
                                    } else if (ttlUsage.compareTo(ttlUsagePre) < 0) {
                                        pcLotUsageChg.setRemark("用量减少");
                                    }
                                    pcLotUsageChg.setTtlUsageNow(ttlUsage);
                                    pcLotUsageChg.setSumUsageNow(pcLotUsage.getSumUsage());
                                    found = true;
                                    break;
                                }
                            }
                            if (!found) {
                                PcLotUsageChg lotUsageChg = new PcLotUsageChg();
                                BeanUtil.copyProperties(pcLotUsage,lotUsageChg);
                                lotUsageChg.setRemark("新增材料");
                                lotUsageChg.setPurFlag(null);
                                lotUsageChg.setRemarkPre(pcLotUsage.getRemark());
                                lotUsageChg.setTtlUsageNow(BigDecimal.valueOf(pcLotUsage.getTtlUsage()));
                                lotUsageChg.setVersion(BigDecimal.valueOf(version));
                                lotUsageChg.setSumUsageNow(pcLotUsage.getSumUsage());
                                pcLotUsageChgList.add(lotUsageChg);
                            }
                        }
                        if (!ObjectUtils.isEmpty(usageChgList)){
                            pcLotExp2Mapper.updatePcLotUsageChgList(usageChgList);
                        }
                        if (!ObjectUtils.isEmpty(pcLotUsageChgList)){
                            pcLotHeadMapper.addPcLotUsageChgList(pcLotUsageChgList);
                        }

                        // 处理子材料
                        if (!ObjectUtils.isEmpty(lotUsageFitList)) {
                            for (PcLotUsageFit pcLotUsageFit : lotUsageFitList) {
                                boolean isUpdated = false;

                                if (!ObjectUtils.isEmpty(lotUsageFitChgList)) {
                                    for (PcLotUsageFitChg lotUsageFitChg : lotUsageFitChgList) {
                                        // 检查是否有重复项（通过字段匹配）
                                        if (pcLotUsageFit.getPartName().equals(lotUsageFitChg.getPartName()) &&
                                                pcLotUsageFit.getMtlNo().equals(lotUsageFitChg.getMtlNo()) &&
                                                pcLotUsageFit.getSubMtlNo().equals(lotUsageFitChg.getSubMtlNo())&&
                                                pcLotUsageFit.getSeqNo().equals(lotUsageFitChg.getSeqNo())) {
                                            lotUsageFitChg.setTtlUsageNow(pcLotUsageFit.getTtlUsage());
                                            lotUsageFitChg.setSubTtlUsageNow(pcLotUsageFit.getSubTtlUsage());
                                            // 标记为已更新
                                            isUpdated = true;
                                        }
                                    }
                                }

                                // 如果没有找到匹配项，新增记录
                                if (!isUpdated) {
                                    PcLotUsageFitChg newLotUsageFitChg = new PcLotUsageFitChg();
                                    BeanUtil.copyProperties(pcLotUsageFit, newLotUsageFitChg);
                                    newLotUsageFitChg.setTtlUsageNow(pcLotUsageFit.getTtlUsage());
                                    newLotUsageFitChg.setSubTtlUsageNow(pcLotUsageFit.getSubTtlUsage());
                                    newLotUsageFitChg.setPurFlag(null);
                                    newLotUsageFitChg.setVersion(BigDecimal.valueOf(version));
                                    pcLotUsageChgFitList.add(newLotUsageFitChg);
                                }
                            }

                            if (!ObjectUtils.isEmpty(lotUsageFitChgList)) {
                                pcLotExp2Mapper.updatePcLotUsageFitChgList(lotUsageFitChgList);
                            }
                        }

                        if (!ObjectUtils.isEmpty(pcLotUsageChgFitList)) {
                            pcLotHeadMapper.addPcLotUsageFitChgList(pcLotUsageChgFitList);
                        }
                    }
                    break;
                case 1:
                    if (ObjectUtils.isEmpty(request.getReason())) {
                        return ResponseInfo.error("请输入取消审核原因!");
                    }
                    if (ObjectUtils.isEmpty(pcLotHead.getCheckFlag())) {
                        return ResponseInfo.error("该指令未审核,不能取消审核!!");
                    }
                    pcLotHeadMapper.updateLotNoCheckUp(request.getLotNo(),companyId,null,null,null);
                    pcLotExp2Service.addPcLotExp2(request.getLotNo(),request.getReason(),companyId,userName,request.getFlag(),version);
                    for (PcLotUsage usage : lotUsageList) {
                        PcLotUsageChg lotUsageChg = new PcLotUsageChg();
                        BeanUtil.copyProperties(usage,lotUsageChg);
                        lotUsageChg.setRemark(null);
                        lotUsageChg.setPurFlag(null);
                        lotUsageChg.setRemarkPre(usage.getRemark());
                        lotUsageChg.setTtlUsagePre(BigDecimal.valueOf(usage.getTtlUsage()));
                        lotUsageChg.setVersion(BigDecimal.valueOf(version+1));
                        lotUsageChg.setSumUsagePre(usage.getSumUsage());
                        pcLotUsageChgList.add(lotUsageChg);
                    }
                    if (!ObjectUtils.isEmpty(pcLotUsageChgList)) {
                        pcLotHeadMapper.addPcLotUsageChgList(pcLotUsageChgList);
                    }

                    //查询子材料记录
                    if (ZStringUtils.isNotEmpty(lotUsageFitList)){
                        for (PcLotUsageFit usage : lotUsageFitList) {
                            PcLotUsageFitChg lotUsageFitChg = new PcLotUsageFitChg();
                            BeanUtil.copyProperties(usage,lotUsageFitChg);
                            lotUsageFitChg.setPurFlag(null);
                            lotUsageFitChg.setTtlUsagePre(usage.getTtlUsage());
                            lotUsageFitChg.setSubTtlUsagePre(usage.getSubTtlUsage());
                            lotUsageFitChg.setVersion(BigDecimal.valueOf(version+1));
                            pcLotUsageChgFitList.add(lotUsageFitChg);
                        }
                        pcLotHeadMapper.addPcLotUsageFitChgList(pcLotUsageChgFitList);
                    }
                    break;
                default:
                    return ResponseInfo.error("参数错误!");
            }
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 整单删除
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getStyleDelete(LotNoRequest request) {
        if (request.getLotNo().isEmpty()){
            return ResponseInfo.error("指令为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo, request.getLotNo()).eq(PcLotHead::getCompanyId,companyId);
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcLotHead)){
            return ResponseInfo.error("指令不存在!");
        }
        if ("Y".equals(pcLotHead.getCheckFlag())){
            return ResponseInfo.error("指令已审核,不能删除!");
        }

        //如果已经订购了，不能删除
        LotAndMtlRequest lotAndMtlRequest = new LotAndMtlRequest();
        lotAndMtlRequest.setCompanyId(companyId);
        lotAndMtlRequest.setLotNo(request.getLotNo());
        List<PurchaseOrderDto> list = materialClearanceMapper.getPurchaseOrder(lotAndMtlRequest);
        if( ObjectUtils.isNotEmpty(list)){
            throw new ServiceErrorException("该指令已订购,不能删除!");
        }

        pcLotHeadMapper.delPcLotGroupAll(request.getLotNo(),companyId);
        pcLotHeadMapper.delPcLotDetailAll(request.getLotNo(),companyId);
        pcLotHeadMapper.delPcLotUsage(request.getLotNo(), companyId);
        pcLotHeadMapper.delSoleDetails(request.getLotNo(),companyId);
        pcLotHeadMapper.delStitchDetails(request.getLotNo(),companyId);
        pcLotHeadMapper.delLastDetails(request.getLotNo(), companyId);
        pcLotHeadMapper.delPcLotUsageHead(request.getLotNo(),companyId);
        LambdaUpdateWrapper<PcLotHead> wrapper2 = new LambdaUpdateWrapper<>();
        wrapper2.eq(PcLotHead::getLotNo, request.getLotNo()).eq(PcLotHead::getCompanyId,companyId);
        pcLotHeadMapper.delete(wrapper2);
        PcLotDelLog delLog = new PcLotDelLog();
        delLog.setLotNo(request.getLotNo());
        delLog.setSysUser(UserIdThread.get().getUserName());
        delLog.setSysDate(LocalDateTime.now());
        delLog.setCompanyId(companyId);
        delLog.setLotType("正式指令");
        pcLotHeadMapper.addPcLotDelLog(delLog);
        return ResponseInfo.ok("操作成功!");
    }

    @Resource
    private PcOutListMapper pcOutListMapper;

    @Resource
    private ProfileConfig profileConfig;

    /**
     * 导出指令单
     * @param lotNo
     * @param response
     */
    @Override
    public void ExportInstructionSheet(String lotNo, int flag, HttpServletResponse response) {
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo, lotNo);
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (!ObjectUtils.isEmpty(pcLotHead)){
            String fileName = pcLotHead.getLotNo()+"_"+ pcLotHead.getStyle() + "_"+pcLotHead.getColor()+"_" +DateUtils.dateTimeNow() + ".xlsx";
            Map<String, Object> map = getKeyValue(pcLotHead);
            //翻单：查询当前指令是否有翻单的指令：前一单形体配色相同（仅仅采购需要）
            String repeatLotNo = pcLotHeadMapper.getRepeatLotNo(pcLotHead);
            String photo = pcOutListMapper.getPhoto(pcLotHead.getStyle(), pcLotHead.getColor(),companyId);
            List<PcLotDetailDto> numberList = pcLotHeadMapper.getCodeDetails(pcLotHead.getLotNo(), pcLotHead.getCompanyId());
            List<SdStyleSizeDto> sizeList = pcLotHeadMapper.getStyleShoeLastDetails(pcLotHead.getStyle(), companyId);
            BigDecimal orderQtyCount=BigDecimal.ZERO;
            BigDecimal surplusQtyCount=BigDecimal.ZERO;
            BigDecimal allCount=BigDecimal.ZERO;
            List<SdStyleSizeDto> newSizeList = new ArrayList<>();
            if (!ObjectUtils.isEmpty(numberList)){
                for (PcLotDetailDto t : numberList) {
                    BigDecimal totalQty = t.getTotalQty();
                    t.setCount(totalQty);
                    allCount=allCount.add(totalQty);
                    if (t.getOrderQty()!=null){
                        orderQtyCount =orderQtyCount.add(t.getOrderQty());
                    }
                    if (t.getSurplusQty()!=null){
                        surplusQtyCount =surplusQtyCount.add(t.getSurplusQty());
                    }
                    if (!ObjectUtils.isEmpty(sizeList)){
                        for (SdStyleSizeDto sizeDto : sizeList) {
                            if (t.getSizeNo().equals(sizeDto.getSizeNo())) {
                                newSizeList.add(sizeDto);
                                break;
                            }
                        }
                    }
                }
            }
            map.put("orderQtyCount",orderQtyCount);
            map.put("surplusQtyCount",surplusQtyCount);
            map.put("allCount",allCount);
            List<PcLotUsageDto> usageDetails = pcLotHeadMapper.getUsageDetails(pcLotHead.getLotNo(), companyId);
            for (PcLotUsageDto t : usageDetails) {
                if (!ObjectUtils.isEmpty(t.getSize1())&&!ObjectUtils.isEmpty(t.getSize2())){
                    String name="("+t.getSize1()+"-"+t.getSize2()+")";
                    String mtlName = t.getMtlName();
                    t.setMtlName(mtlName+name);
                }
                if ("HF".equals(pcLotHead.getCompanyId())||profileConfig.isVNMProfile()){
                    if (!"B".equals(t.getUsageType())){
                        BigDecimal ttlUsage = t.getTtlUsage();
                        BigDecimal addUsage = ttlUsage.multiply(new BigDecimal(0.05)).setScale(1, RoundingMode.HALF_UP);
                        t.setAddUsage(addUsage);
                    }
                }
            }
            List<YfBomMemoNew2Dto> noteList = largeCargoUsageMapper.getNotesForFilingList(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            map.put("numberList",numberList);
            map.put("sizeList",newSizeList);
            map.put("usageDetails",usageDetails);
            map.put("noteList",noteList);
            String userName = UserIdThread.get().getUserName();
            LocalDate date = LocalDate.now();
            map.put("userName",userName);
            map.put("date",date);
            map.put("sheets",Arrays.asList(0));
            //如果是采购的就查看翻单
            if(flag == 1){
                map.put("reamrk","翻单备注："); //翻单备注
                map.put("repeatLotNo",repeatLotNo); //翻单指令号
            }

            TemplateExportParams templateParams = new TemplateExportParams("templates/指令生产明细模板.xlsx", true);
            templateParams.setColForEach(true);
            try {
                byte[] imageBytes = ImageUtils.readAndResizeImage(photo, 190, 400);
                ExcelUtils.setResponseZF(response, fileName);
                ExcelPoiUtils.writeExcelWithPictureToResponse(response, templateParams, map, imageBytes, 25, 7, 3, 4);
            } catch (Exception e) {
                log.error(pcLotHead.getLotNo()+"_"+ pcLotHead.getStyle() + "_"+pcLotHead.getColor()+"表导出失败, 错误信息: {}", e.getMessage());
                throw new ServiceErrorException("指令生产明细导出失败!");
            }
        }
    }

    private Map<String,Object> getKeyValue(PcLotHead pcLotHead){
        Map<String, Object> map = new HashMap<>();
        map.put("lotNo",pcLotHead.getLotNo());
        map.put("styleType",pcLotHead.getStyleType());
        map.put("orderDate",pcLotHead.getOrderDate());
        map.put("deliveryDate",pcLotHead.getDeliveryDate());
        map.put("custom",pcLotHead.getCustom());
        map.put("customPo",pcLotHead.getCustomPo());
        map.put("color",pcLotHead.getColor());
        map.put("style",pcLotHead.getStyle());
        map.put("lastNo",pcLotHead.getLastNo());
        map.put("colorCode",pcLotHead.getColorCode());
        map.put("developmentNo",pcLotHead.getDevelopmentNo());
        map.put("moldNo",pcLotHead.getMoldNo());
        map.put("soleVendor",pcLotHead.getSoleVendor());
        if ("HF".equals(pcLotHead.getCompanyId())||profileConfig.isVNMProfile()){
            map.put("lotRemark","总用量包含预加量");
        }else {
            map.put("lotRemark",pcLotHead.getLotRemark());
        }
        return map;
    }

    /**
     * 刷新型体
     * @param request
     * @return
     */
    @Override
    public ResponseInfo RefreshTheBody(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())){
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId);
        PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcLotHead)){
            return ResponseInfo.error("指令不存在,请核实!");
        }
        if ("Y".equals(pcLotHead.getCheckFlag())){
            return ResponseInfo.warn("指令已审核,不能刷新型体!");
        }
        StyleDataDto colorPhoto = pcLotHeadMapper.getSdStyleColorPhoto(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
        if (ObjectUtils.isEmpty(colorPhoto)){
            return ResponseInfo.error("型体不存在,请核实!");
        }
        pcLotHead.setCustom(colorPhoto.getCustNo());
        pcLotHead.setSeason(colorPhoto.getSeason());
        pcLotHead.setDevelopmentNo(colorPhoto.getDevCode());
        pcLotHead.setCutNo(colorPhoto.getCutTool());
        pcLotHead.setMoldNo(colorPhoto.getSolePart());
        pcLotHead.setLastNo(colorPhoto.getLastMold());
        pcLotHead.setSoleVendor(colorPhoto.getSoleVendor());
        pcLotHead.setColorCode(colorPhoto.getColorCode());
        LambdaUpdateWrapper<PcLotHead> updateWrapper = new LambdaUpdateWrapper<PcLotHead>().eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId,companyId);
        pcLotHeadMapper.update(pcLotHead, updateWrapper);
        return ResponseInfo.ok("操作成功!");
    }

    @Override
    public void downloadStyleData(HttpServletResponse response, PcLotHeadRequest request) throws IOException {
        SysUserTokenDTO dto = UserIdThread.get();
        //查询所有指令信息
        List<PcLotHeadDto> styleDetails = pcLotHeadMapper.getStyleDetails(request,dto);
        ExcelUtils.creatByTemplate(response, "指令资料导出模板.xls", "指令资料_"+DateUtils.dateTimeNow(), styleDetails);

    }

    /**
     * 导号码明细（含预先补）
     * @param request
     * @param response
     */
    @Override
    public void ExportSizeDetail(PcLotHeadRequest request, HttpServletResponse response) {
        //查询所有指令信息
        String companyId = UserIdThread.get().getCompanyId();
        List<PcLotHeadDto2> dataLotNos = pcLotHeadMapper.getStyleDetails2(request,companyId);
        List<String> lotNos = dataLotNos.stream().map(PcLotHeadDto2::getLotNo).collect(Collectors.toList());
        //根据指令批量查询的号码的数量
        List<PcLotDetailDto> dataCodes = pcLotHeadMapper.getBatchCodeDetails(lotNos,companyId);
        //根据指令批量查询号码明细数据》》表头
        List<String> headCodes = pcLotHeadMapper.getBatchCode(lotNos,companyId);

        // 组装一下数据
        List<PcLotHeadDto2> badyList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(dataLotNos)){
            for (PcLotHeadDto2 lotHead2 : dataLotNos) {
                if(ObjectUtils.isNotEmpty(headCodes)){
                    for (PcLotDetailDto dataCode : dataCodes) {
                        if(dataCode.getLotNo().equals(lotHead2.getLotNo())){
                            lotHead2.getCodeList().add(dataCode);
                            badyList.add(lotHead2);
                        }
                    }
                }
            }
        }


        Map map = new HashMap<>();
//        map.put("list",list);

        /*自定义模板数据*/
        //头
        List<List<String>> dateList = new ArrayList<>();
        List<String> headList1 = new ArrayList<>();
        headList1.addAll(Arrays.asList("指令", "型体", "颜色", "下单日期","交期","订单数","预补数","底模","楦头"));
        headList1.addAll(headCodes);


        for (String h : headList1) {
            for (PcLotHeadDto2 dto2 : badyList) {

            }
        }

//        ExcelUtils.creatByTemplate(response,"指令号码明细表模板.xls","指令号码明细表_"+DateUtils.dateTimeNow(),list);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void headListUpNotNull(List<PcLotHead> request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*数据更新*/
        for (PcLotHead r : request) {
            LambdaQueryWrapper<PcLotHead> wrapper=new LambdaQueryWrapper<PcLotHead>()
                    .eq(PcLotHead::getLotNo,r.getLotNo())
                    .eq(PcLotHead::getCompanyId,companyId);
            pcLotHeadMapper.update(r,wrapper);
        }
    }

    @Override
    public void lotCheck(List<String> lotNoList) {
        String companyId = UserIdThread.get().getCompanyId();
        /*对原有指令去重*/
        Set<String> lotNoSet = new HashSet<>(lotNoList);
        /*获取存在的指令*/
        List<PcLotHead> list = lambdaQuery().eq(PcLotHead::getCompanyId, companyId)
                .select(PcLotHead::getLotNo)
                .in(PcLotHead::getLotNo, lotNoList)
                .groupBy(PcLotHead::getLotNo).list();
        /*存在判断*/
        if (ArrayUtils.isEmpyt(list)){
            throw new ServiceErrorException("指令全部不存在");
        }
        if (list.size()!=lotNoSet.size()){
            List<String> collect = list.stream().map(PcLotHead::getLotNo).collect(Collectors.toList());
            List<String> miss = ArrayUtils.findMiss(lotNoSet, collect);
            if (ArrayUtils.isNoEmpyt(miss)) {
                throw new ServiceErrorException("指令" + miss.get(0) + "不存在");
            }else {
                log.warn("\n错误接口：lotCheck\n错误原因：指令判断异常\n输入指令：{}\n查询到的指令：{}",lotNoSet,collect);
            }
        }
    }

    @Override
    public List<String> seasonBack(String season) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取季节*/
        List<PcLotHead> headList = lambdaQuery().select(PcLotHead::getSeason)
                .like(StringUtils.isNotEmpty(season), PcLotHead::getSeason, season)
                .eq(PcLotHead::getCompanyId, companyId)
                .groupBy(PcLotHead::getSeason)
                .last(StringUtils.isNotEmpty(season), "ORDER BY IF(SEASON = " + season + ",0,1)").list();
        if (ArrayUtils.isEmpyt(headList)){
            return new ArrayList<>();
        }
        return headList.stream()
                .filter(Objects::nonNull)
                .map(PcLotHead::getSeason)
                .collect(Collectors.toList());
    }

    /**
     * 导出指令
     * @param request
     * @param response
     * @return
     */
    @Override
    public void exportLotNo(PcLotHeadRequest request, HttpServletResponse response) {
        //先查询指令数据
        SysUserTokenDTO dto = UserIdThread.get();
        //查询所有指令信息
        List<PcLotHeadDto> lotList = pcLotHeadMapper.getStyleDetails(request,dto);
        //统计订单数量预补数量
        PcLotHeadCountDto count = pcLotHeadMapper.orderCount(request,dto);
        Map map = new HashMap<>();
        map.put("lotList",lotList);
        map.put("c",count);

        //导出
        //文件名构建
        String fileName = "指令数据表_" +DateUtils.dateTimeNow() + ".xlsx";
        try {
            ExcelUtils.setResponseZF(response, fileName);
            String templatePath =  "templates/指令数据表模板.xlsx";
            ExcelPoiUtils.writeExcelList(response, map, templatePath, fileName);
        } catch (Exception e) {
            log.error("指令数据表导出失败, 错误信息: {}", e.getMessage());
            throw new ServiceErrorException("导出指令数据表失败");
        }
    }
}
